#include <iomanip>
#include <iostream>

#include <libgen.h>

#include "src/CmdParser.h"

using namespace czj::util;

int main(int argc, char **argv) {
	enum ParameterName {
		ADULT,
		MARRIED,
		NAME,
		COUNTRY,
		WORKS,
		HOBBIES,
		FATHER,
		MOTHER
	};

	CmdParser cmdParser(basename(argv[0]));

	cmdParser.bindHelpKey("-?");
	cmdParser.bindHelpKey("--help");
	cmdParser.addBool(ADULT, "Adult");
	cmdParser.bindBoolKey(ADULT, "-a");
	cmdParser.bindBoolKey(ADULT, "--adult");
	cmdParser.addBool(MARRIED, "Married");
	cmdParser.bindBoolKey(MARRIED, "-m");
	cmdParser.bindBoolKey(MARRIED, "--married");
	cmdParser.addVariable(NAME, "Name", false);
	cmdParser.bindVariableKey(NAME, "-n", "hint");
	cmdParser.bindVariableExpression(NAME, "--name", "=", "hint");
	cmdParser.addVariable(COUNTRY, "Country", true);
	cmdParser.bindVariableKey(COUNTRY, "-c", "hint");
	cmdParser.bindVariableExpression(COUNTRY, "--country", "=", "hint", "china");
	cmdParser.addList(WORKS, "Works", false);
	cmdParser.bindListKey(WORKS, "-w", "hint");
	cmdParser.bindListExpression(WORKS, "--work", "=", "hint");
	cmdParser.addList(HOBBIES, "Hobbies", true);
	cmdParser.bindListKey(HOBBIES, "-h", "hint");
	cmdParser.bindListExpression(HOBBIES, "--hobby", "=", "hint", "sleeping");
	cmdParser.addOperand(FATHER, "Father", "father");
	cmdParser.addOperand(MOTHER, "Mother", "mother");
	cmdParser.enableExtension("Friends", "friends");

	const char *const arguments[] = {"-?", "--help",
									 "-a", "--adult",
									 "-n", "zm", "--name=zjiemain",
									 "-c", "cn", "--country",
									 "-w", "student", "--work=engineer", "--work=designer",
									 "-h", "eating", "--hobby=playing", "--hobby",
									 "dad", "mom",
									 "linux", "git", "clion"};
	if (cmdParser.parse(sizeof(arguments) / sizeof(const char *), arguments)) {
		bool first;
		std::cout << std::left << std::setw(12) << "Adult:" << std::boolalpha << cmdParser.getBool(ADULT) << std::endl;
		std::cout << std::left << std::setw(12) << "Married:" << std::boolalpha << cmdParser.getBool(MARRIED) << std::endl;
		std::cout << std::left << std::setw(12) << "Name:" << cmdParser.getVariable(NAME) << std::endl;
		std::cout << std::left << std::setw(12) << "Country:" << cmdParser.getVariable(COUNTRY) << std::endl;
		std::cout << std::left << std::setw(12) << "Works:";
		first = true;
		for (auto const &item : cmdParser.getList(WORKS)) {
			if (!first) {
				std::cout << " ";
			}
			std::cout << item;
			first = false;
		}
		std::cout << std::endl;
		std::cout << std::left << std::setw(12) << "Hobbies:";
		first = true;
		for (auto const &item : cmdParser.getList(HOBBIES)) {
			if (!first) {
				std::cout << " ";
			}
			std::cout << item;
			first = false;
		}
		std::cout << std::endl;
		std::cout << std::left << std::setw(12) << "Father:" << cmdParser.getOperand(FATHER) << std::endl;
		std::cout << std::left << std::setw(12) << "Mother:" << cmdParser.getOperand(MOTHER) << std::endl;
		std::cout << std::left << std::setw(12) << "Friends:";
		first = true;
		for (auto const &item : cmdParser.getExtension()) {
			if (!first) {
				std::cout << " ";
			}
			std::cout << item;
			first = false;
		}
		std::cout << std::endl;
	}
	else {
		std::cout << "[ERR] (" << __FILE__ << ", " << __LINE__ << ") " << "info" << std::endl;
	}

	return 0;
}
